﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;
using Futaba.SBus.Readers;
using Futaba.SBus.Channels;
using System.Linq;

namespace Futaba.SBus.Tests
{
	[TestClass]
	public class ChannelParserTests : BaseTest
	{

		[TestMethod, TestCategory("SBUS")]
		[DeploymentItem(@"Samples\TxData\ch1-4_0.log")]
		public void TryParseChannelsMultiReads()
		{
			var reader = new FileSbusStreamReader("ch1-4_0.log", packetsPerSecond: 20);
			reader.OpenPort();
			var target = new ChannelParser();
			target.Reader = reader;

			var lastSkipped = 0;
			for (var i = 1; i <= 10; i++)
			{
				var actual = target.ReadPacket();
				Assert.IsTrue(actual);
				Assert.IsTrue(target.BytesSkipped >= (i == 1 ? 0 : lastSkipped + 20)); //skip telemetry
				Assert.AreEqual(i, target.PacketsReceived);
				lastSkipped = target.BytesSkipped;
			}

			reader.ReleasePort();

			var ch = target.ItemsCollection.OrderBy(c => c.ChannelId).ToArray();

			PrintChannels(ch);
			Assert.AreEqual(0, ch[0].CurrentValue);
			Assert.AreEqual(0, ch[1].CurrentValue);
			Assert.AreEqual(0, ch[2].CurrentValue);
			Assert.AreEqual(0, ch[3].CurrentValue);
			Assert.AreEqual(-100, ch[4].CurrentValue);
			Assert.AreEqual(-155, ch[16].CurrentValue);
			Assert.AreEqual(-155, ch[17].CurrentValue);
		}

		[TestMethod, TestCategory("SBUS")]
		[DeploymentItem(@"Samples\TxData\ch1-4_0.log")]
		public void TryParseChannels1()
		{
			var reader = new FileSbusStreamReader("ch1-4_0.log", packetsPerSecond: 20);
			reader.OpenPort();
			var target = new ChannelParser();
			target.Reader = reader;

			var actual = target.ReadPacket();

			reader.ReleasePort();

			Assert.IsTrue(actual);
			var ch = target.ItemsCollection.OrderBy(c => c.ChannelId).ToArray();

			PrintChannels(ch);
			Assert.AreEqual(1, target.PacketsReceived);
			Assert.AreEqual(0, target.PacketErrors);
			Assert.AreEqual(0, ch[0].CurrentValue);
			Assert.AreEqual(0, ch[1].CurrentValue);
			Assert.AreEqual(0, ch[2].CurrentValue);
			Assert.AreEqual(0, ch[3].CurrentValue);
			Assert.AreEqual(-100, ch[4].CurrentValue);
			Assert.AreEqual(-155, ch[16].CurrentValue);
			Assert.AreEqual(-155, ch[17].CurrentValue);
		}

		[TestMethod, TestCategory("SBUS")]
		[DeploymentItem(@"Samples\TxData\ch1_-100-ch2-4_0.log")]
		public void TryParseChannels2()
		{
			var reader = new FileSbusStreamReader("ch1_-100-ch2-4_0.log", packetsPerSecond: 20);
			reader.OpenPort();

			var target = new ChannelParser();
			target.Reader = reader;

			var actual = target.ReadPacket();

			reader.ReleasePort();

			Assert.IsTrue(actual);
			var ch = target.ItemsCollection.OrderBy(c => c.ChannelId).ToArray();

			PrintChannels(ch);
			Assert.AreEqual(1, target.PacketsReceived);
			Assert.AreEqual(0, target.PacketErrors);
			Assert.AreEqual(-100, ch[0].CurrentValue);
			Assert.AreEqual(0, ch[1].CurrentValue);
			Assert.AreEqual(0, ch[2].CurrentValue);
			Assert.AreEqual(0, ch[3].CurrentValue);
			Assert.AreEqual(-100, ch[4].CurrentValue);
			Assert.AreEqual(-155, ch[16].CurrentValue);
			Assert.AreEqual(-155, ch[17].CurrentValue);
		}

		[TestMethod, TestCategory("SBUS")]
		[DeploymentItem(@"Samples\TxData\ch1_+100-ch2-4_0.log")]
		public void TryParseChannels3()
		{
			var reader = new FileSbusStreamReader("ch1_+100-ch2-4_0.log", packetsPerSecond: 20);
			reader.OpenPort();

			var target = new ChannelParser();
			target.Reader = reader;

			var actual = target.ReadPacket();

			reader.ReleasePort();

			Assert.IsTrue(actual);
			var ch = target.ItemsCollection.OrderBy(c => c.ChannelId).ToArray();

			PrintChannels(ch);
			Assert.AreEqual(1, target.PacketsReceived);
			Assert.AreEqual(0, target.PacketErrors);
			Assert.AreEqual(100, ch[0].CurrentValue);
			Assert.AreEqual(0, ch[1].CurrentValue);
			Assert.AreEqual(0, ch[2].CurrentValue);
			Assert.AreEqual(0, ch[3].CurrentValue);
			Assert.AreEqual(-100, ch[4].CurrentValue);
			Assert.AreEqual(-155, ch[16].CurrentValue);
			Assert.AreEqual(-155, ch[17].CurrentValue);
		}

		[TestMethod, TestCategory("SBUS")]
		[DeploymentItem(@"Samples\TxData\ch1_+152_ch5_+139_DG1_on.log")]
		public void TryParseChannels4()
		{
			var reader = new FileSbusStreamReader("ch1_+152_ch5_+139_DG1_on.log", packetsPerSecond: 20);
			reader.OpenPort();

			var target = new ChannelParser();
			target.Reader = reader;

			var actual = target.ReadPacket();

			reader.ReleasePort();

			Assert.IsTrue(actual);
			var ch = target.ItemsCollection.OrderBy(c => c.ChannelId).ToArray();

			PrintChannels(ch);
			Assert.AreEqual(1, target.PacketsReceived);
			Assert.AreEqual(0, target.PacketErrors);
			Assert.AreEqual(152, ch[0].CurrentValue);
			Assert.AreEqual(0, ch[1].CurrentValue);
			Assert.AreEqual(0, ch[2].CurrentValue);
			Assert.AreEqual(0, ch[3].CurrentValue);
			Assert.AreEqual(139, ch[4].CurrentValue);
			Assert.AreEqual(155, ch[16].CurrentValue);
			Assert.AreEqual(-155, ch[17].CurrentValue);
		}

		private void PrintChannels(Channel[] ch)
		{
			foreach (var c in ch)
				TestContext.WriteLine("{0}", c);
		}

	}
}
